package com.ushine.web.component.task.config;

import com.ushine.web.component.task.AsyncConstant;
import com.ushine.web.component.task.handler.TemplateRejectedExecutionHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.util.concurrent.Executor;

/**
 * @Author: yls
 * @Date: 2022/02/27 11:47
 * @Description: 线程池统一配置
 * @Version 1.0
 */
@EnableAsync
@Component
@Configuration
@Slf4j
public class AsyncConfig {
    private final BusinessAsyncConfig businessAsyncConfig;

    private final ExportAsyncConfig exportAsyncConfig;

    private final ImportAsyncConfig importAsyncConfig;

    @Autowired
    public AsyncConfig(BusinessAsyncConfig businessAsyncConfig, ExportAsyncConfig exportAsyncConfig, ImportAsyncConfig importAsyncConfig) {
        this.businessAsyncConfig = businessAsyncConfig;
        this.exportAsyncConfig = exportAsyncConfig;
        this.importAsyncConfig = importAsyncConfig;
    }


    @Bean(AsyncConstant.BUSINESS_EXECUTOR)
    public Executor getBusinessExecutor() {
        return initExecutor(businessAsyncConfig);
    }

    @Bean(AsyncConstant.EXPORT_EXECUTOR)
    public Executor getExportExecutor() {
        return initExecutor(exportAsyncConfig);
    }

    @Bean(AsyncConstant.IMPORT_EXECUTOR)
    public Executor getImportExecutor() {
        return initExecutor(importAsyncConfig);
    }

    public Executor initExecutor(AsyncConstantsConfig constantsConfig) {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        //核心线程数
        taskExecutor.setCorePoolSize(constantsConfig.getCorePoolSize());
        // 最大线程数
        taskExecutor.setMaxPoolSize(constantsConfig.getMaxPoolSize());
        //
        taskExecutor.setKeepAliveSeconds(constantsConfig.getKeepAliveSeconds());
        //线程池所使用的缓冲队列
        taskExecutor.setQueueCapacity(constantsConfig.getQueueCapacity());
        //等待任务在关机时完成--表明等待所有线程执行完
        taskExecutor.setWaitForTasksToCompleteOnShutdown(constantsConfig.getWaitForTasksToCompleteOnShutdown());
        // 等待时间 （默认为0，此时立即停止），并没等待xx秒后强制停止
        taskExecutor.setAwaitTerminationSeconds(constantsConfig.getAwaitTerminationSeconds());
        //  线程名称前缀
        taskExecutor.setThreadNamePrefix(constantsConfig.getThreadNamePrefix());
        //队列满，线程被拒绝执行策略，这里采用自定义拒绝策略
        taskExecutor.setRejectedExecutionHandler(new TemplateRejectedExecutionHandler());
        //ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常
        //ThreadPoolExecutor.DiscardPolicy：丢弃任务，但是不抛出异常。
        //ThreadPoolExecutor.DiscardOldestPolicy：丢弃队列最前面。
        //ThreadPoolExecutor.CallerRunsPolicy：由调用者处理该任务 。
        // 初始化
        taskExecutor.initialize();
        return taskExecutor;
    }
}
